package com.sugon.controller.module;

import cn.afterturn.easypoi.entity.vo.TemplateExcelConstants;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelXorHtmlUtil;
import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.AutoLog;
import com.sugon.annotation.LimitSubmit;
import com.sugon.annotation.NonBusinessParamValid;
import com.sugon.entity.ModuleArchivesEntity;
import com.sugon.entity.SysDeptEntity;
import com.sugon.modules.mold.consts.MoldState;
import com.sugon.modules.mold.model.vo.MoldStatusUpdateVO;
import com.sugon.modules.mold.service.IMoldArchivesManager;
import com.sugon.modules.sys.consts.SysDeptConst;
import com.sugon.service.ModuleArchivesService;
import com.sugon.service.ModuleTimesPositionService;
import com.sugon.service.SysConfigService;
import com.sugon.service.SysDeptService;
import com.sugon.utils.*;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 模具档案信息Controller
 *
 * @author YuXD
 * @date 2023-01-19
 */
@Controller
@RequestMapping("modulearchives")
public class ModuleArchivesController {
    @Autowired
    private ModuleArchivesService moduleArchivesService;
    @Autowired
    private IMoldArchivesManager moldArchivesManager;
    @Autowired
    private SysDeptService deptService;
    @Autowired
    private SysConfigService configService;
    @Resource
    private ModuleTimesPositionService moldPositionTimesService;

    /**
     * 更新模具状态
     */
    @NonBusinessParamValid
    @ResponseBody
    @PostMapping("/updateMoldStatus")
    public R updateMoldStatus(@Validated @RequestBody MoldStatusUpdateVO moldStatusUpdateParam, BindingResult bindingResult) {
        // 校验模具是否存在
        ModuleArchivesEntity moduleArchives = moduleArchivesService.queryObject(moldStatusUpdateParam.getMoldId());
        if (moduleArchives == null) {
            return R.error("模具不存在！");
        }
        // 设置并更新模具状态
        moduleArchives.setCurrentState(moldStatusUpdateParam.getMoldStatus());
        return moduleArchivesService.update(moduleArchives) > 0 ? R.ok() : R.error();
    }

    /**
     * 校验模具底层编码是否重复
     */
    @RequestMapping("/isExists")
    @ResponseBody
    public R isExists(@RequestParam Map<String, Object> params) {
        String rows = "";
        List<ModuleArchivesEntity> moldList = moduleArchivesService.queryList(params);
        if (CollectionUtil.isNotEmpty(moldList)) {
            List<String> moldNoList = moldList.stream().map(ModuleArchivesEntity::getModuleNo).collect(Collectors.toList());
            String suffix = "";
            if (moldNoList.size() > 2) {
                moldNoList = CollectionUtil.sub(moldNoList, 0, 2);
                suffix = "等";
            }
            rows = CollectionUtil.join(moldNoList, "，") + suffix;
        }
        return R.ok().put("rows", rows);
    }

    /**
     * 加载车间模具健康状态数据
     *
     * @param foundryWorkshopId 铸造车间ID
     * @param productModel      模具机型
     * @param moldStatus        模具状态
     */
    @ResponseBody
    @RequestMapping("/loadMoldStatusData")
    public R loadWorkshopMoldHealthyStatusData(@RequestParam String foundryWorkshopId, String productModel, Integer moldStatus) {
        // 校验车间是否存在
        SysDeptEntity dept = deptService.queryObject(foundryWorkshopId);
        if (dept == null) {
            return R.error("车间不存在，请确认！");
        }
        return R.ok().put("moldStatusDataList", moldArchivesManager.loadWorkshopMoldHealthyStatusData(foundryWorkshopId, productModel, moldStatus));
    }

    /**
     * 查看列表
     */
    @RequestMapping("/list")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params) {

        //查询列表数据
        Query query = new Query(params);

        List<ModuleArchivesEntity> moduleArchivesList = moduleArchivesService.queryList(query);
        int total = moduleArchivesService.queryTotal(query);

        PageUtils pageUtil = new PageUtils(moduleArchivesList, total, query.getLimit(), query.getPage());

        return R.ok().put("page", pageUtil);
    }

    /**
     * 查看可用模具列表：排除模具报废或镶块报废的模具
     */
    @RequestMapping("/listAvailable")
    @ResponseBody
    public R listAvailable(@RequestParam Map<String, Object> params) {
        // 设置排除的状态列表
        params.put("excludeStatusList", CollectionUtil.newArrayList(MoldState.MUJUBAOFEI.getState(), MoldState.XIANGKUAIBAOFEI.getState()));
        // 车间用户只可以看自己的车间
        String workshop = ShiroUtils.getWorkshop();
        if (StrUtil.isNotEmpty(workshop) && !SysDeptConst.ZZGYC_CODE.equals(workshop)) {
            params.put("subShop", workshop);
        }
        //查询列表数据
        Query query = new Query(params);
        List<ModuleArchivesEntity> moduleArchivesList = moduleArchivesService.queryList(query);
        int total = moduleArchivesService.queryTotal(query);
        PageUtils pageUtil = new PageUtils(moduleArchivesList, total, query.getLimit(), query.getPage());
        return R.ok().put("page", pageUtil);
    }

    /**
     * 查看列表
     */
    @RequestMapping("/listAll")
    @ResponseBody
    public R listAll(@RequestParam Map<String, Object> params) {
        return R.ok().put("list", moduleArchivesService.queryList(params));
    }

    /**
     * 查询出位于工单中的模具列表
     *
     * @param params
     * @return
     */
    @RequestMapping("/listTicketMold")
    @ResponseBody
    public R listTicketMold(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Query query = new Query(params);
        List<ModuleArchivesEntity> moduleArchivesList = moduleArchivesService.queryListTicketMold(query);
        int total = moduleArchivesService.queryTotalTicketMold(query);
        PageUtils pageUtil = new PageUtils(moduleArchivesList, total, query.getLimit(), query.getPage());
        return R.ok().put("page", pageUtil);
    }

    /**
     * 查看信息
     */
    @RequestMapping("/info/{id}")
//    @RequiresPermissions("modulearchives:info")
    @ResponseBody
    public R info(@PathVariable("id") String id) {
        ModuleArchivesEntity moduleArchives = moduleArchivesService.queryObject(id);

        return R.ok().put("moduleArchives", moduleArchives);
    }

    @LimitSubmit(key = "addMold:%s")
    @AutoLog("模具档案信息--保存")
    @RequestMapping("/save")
    @RequiresPermissions("modulearchives:save")
    @ResponseBody
    public R save(@RequestBody ModuleArchivesEntity moduleArchives) {
        // 校验低层设备码是否重复
        String lastCode = moduleArchives.getLastCode();
        if (StrUtil.isNotEmpty(lastCode)) {
            int count = moduleArchivesService.countByLastCode(null, lastCode);
            if (count > 0) {
                return R.error("模具低层编码不允许重复！");
            }
        }
        // 保存模具信息，并保存模具位置关联
        moldArchivesManager.newlyAdd(moduleArchives);
        return R.ok();
    }

    @LimitSubmit(key = "updateMold:%s")
    @AutoLog("模具档案信息--修改")
    @RequestMapping("/update")
    @RequiresPermissions("modulearchives:update")
    @ResponseBody
    public R update(@RequestBody ModuleArchivesEntity moduleArchives) {
        ModuleArchivesEntity moldInDB = moduleArchivesService.queryObject(moduleArchives.getId());
        if (moldInDB == null) {
            return R.error("模具不存在，请确认！");
        }
        // 校验低层设备码是否重复
        String lastCode = moduleArchives.getLastCode();
        if (StrUtil.isNotEmpty(lastCode)) {
            int count = moduleArchivesService.countByLastCode(moduleArchives.getId(), lastCode);
            if (count > 0) {
                return R.error("模具低层编码不允许重复！");
            }
        }
        // 更新模具信息
        moldArchivesManager.update(moduleArchives);
        return R.ok();
    }

    /**
     * 删除
     */
    @AutoLog("模具档案信息--删除")
    @RequestMapping("/delete")
    @RequiresPermissions("modulearchives:delete")
    @ResponseBody
    public R delete(@RequestBody String[] ids) {
        moduleArchivesService.deleteBatch(ids);

        return R.ok();
    }

    /**
     * 查看所有列表
     */
    @RequestMapping("/queryAll")
    @ResponseBody
    public R queryAll(@RequestParam Map<String, Object> params) {

        List<ModuleArchivesEntity> list = moduleArchivesService.queryList(params);

        return R.ok().put("list", list);
    }

    /**
     * excel导入
     */
    @RequestMapping("/import")
    @RequiresPermissions("modulearchives:import")
    @ResponseBody
    public R importE(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }

        int count = moduleArchivesService.importE(file);

        return R.ok("成功导入" + count + "条数据");
    }

    /**
     * 模具各位置 近days天内的模次累计数据预览
     *
     * @param action 下载还是在线预览
     * @param moldId 模具ID
     * @param days   天数
     * @throws IOException
     */
    @RequestMapping("/{action}")
    public void onlinePreview(@PathVariable("action") String action, @RequestParam String moldId, @RequestParam Integer days, ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws IOException {

        ModuleArchivesEntity mold = moduleArchivesService.queryObject(moldId);
        Assert.notNull(mold);

        TemplateExportParams templateExportParams = new TemplateExportParams(configService.getPoiTemplatePath() + "moldPositionMoldTimesPreviewTemplate.xlsx");
        templateExportParams.setColForEach(true);
        // 获取设备维护计划预览模板数据
        Map<String, Object> moldPosTimesPreviewData = moldPositionTimesService.generateMoldPositionTimesPreviewData(moldId, days);
        if ("onlinePreview".equals(action)) {
            // 构建EXCEL
            Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, moldPosTimesPreviewData);
            // 生成HTML预览
            ExcelToHtmlParams excelToHtmlParams = new ExcelToHtmlParams(workbook);
            response.setHeader("Content-Type", "text/html;charset=utf-8");
            response.getOutputStream().write(ExcelXorHtmlUtil.excelToHtml(excelToHtmlParams).getBytes());
        } else {
            modelMap.put(TemplateExcelConstants.FILE_NAME, "模具[" + mold.getModuleNo() + "]近" + days + "天备件寿命统计");
            modelMap.put(TemplateExcelConstants.PARAMS, templateExportParams);
            modelMap.put(TemplateExcelConstants.MAP_DATA, moldPosTimesPreviewData);
            PoiBaseView.render(modelMap, request, response, TemplateExcelConstants.EASYPOI_TEMPLATE_EXCEL_VIEW);
        }
    }
}
